Add missing NULL on valist.
authorOwen Taylor <otaylor@redhat.com>
Thu, 29 Mar 2001 00:24:58 +0000 (00:24 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Thu, 29 Mar 2001 00:24:58 +0000 (00:24 +0000)
Wed Mar 28 19:20:43 2001  Owen Taylor  <otaylor@redhat.com>

* gtk/testtext.c (create_buffer): Add missing NULL on
valist.

* gtk/gtkcheckmenuitem.c (gtk_check_menu_item_class_init): Fix
c-n-p problem with INCONSISTENT property.

        [ Patch from Havoc Pennington  <hp@redhat.com> ]

* gtk/gtkentry.h (struct _GtkEntryClass): add same populate_popup
hook.

* gtk/gtktextview.h (struct _GtkTextViewClass): add populate_popup
signal as a hook for extending the default popup menu

* gtk/gtkimmulticontext.c (gtk_im_multicontext_append_menuitems):
use radio menu items for the input method menuitems

* gtk/gtkimcontextsimple.c (check_hex): do better validation of
inserted unicode from Ctrl-Shift-hex input method

* gtk/gtktextbtree.c (_gtk_text_btree_insert): remove utf8
validatation here, already done at GtkTextBuffer level.

* gtk/gtkwidget.c (gtk_widget_class_init): add binding set, add
popup_menu run action signal and Shift+F10 and Menu keybindings.

* gtk/gtkentry.c: implement a default handler for popup_menu

* gtk/gtktextview.c: implement a default handler for popup_menu

* gtk/gtkmenu.c (gtk_menu_popup): select first item if popup is
from a key event

* gtk/gtklabel.c: remove "trailer" cruft

21 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkcheckmenuitem.c
gtk/gtkentry.c
gtk/gtkentry.h
gtk/gtkimcontextsimple.c
gtk/gtkimmulticontext.c
gtk/gtkmenu.c
gtk/gtktextbtree.c
gtk/gtktextbuffer.c
gtk/gtktextview.c
gtk/gtktextview.h
gtk/gtkwidget.c
gtk/gtkwidget.h
gtk/testtext.c
tests/testtext.c

index 51700f8c4573a01c4e55c696db7fe2fea81c4253..1d47c86b5a2724a600db27b86dbde85bc8de9f97 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+Wed Mar 28 19:20:43 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/testtext.c (create_buffer): Add missing NULL on
+       valist.
+
+       * gtk/gtkcheckmenuitem.c (gtk_check_menu_item_class_init): Fix
+       c-n-p problem with INCONSISTENT property.
+
+        [ Patch from Havoc Pennington  <hp@redhat.com> ]
+
+       * gtk/gtkentry.h (struct _GtkEntryClass): add same populate_popup
+       hook.
+
+       * gtk/gtktextview.h (struct _GtkTextViewClass): add populate_popup
+       signal as a hook for extending the default popup menu
+
+       * gtk/gtkimmulticontext.c (gtk_im_multicontext_append_menuitems):
+       use radio menu items for the input method menuitems
+
+       * gtk/gtkimcontextsimple.c (check_hex): do better validation of 
+       inserted unicode from Ctrl-Shift-hex input method
+
+       * gtk/gtktextbtree.c (_gtk_text_btree_insert): remove utf8
+       validatation here, already done at GtkTextBuffer level.
+
+       * gtk/gtkwidget.c (gtk_widget_class_init): add binding set, add
+       popup_menu run action signal and Shift+F10 and Menu keybindings.
+
+       * gtk/gtkentry.c: implement a default handler for popup_menu
+
+       * gtk/gtktextview.c: implement a default handler for popup_menu
+
+       * gtk/gtkmenu.c (gtk_menu_popup): select first item if popup is
+       from a key event
+       
+       * gtk/gtklabel.c: remove "trailer" cruft
+
 Wed Mar 28 17:27:12 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtkrbtree.c (_gtk_rbtree_reorder): new function to
index 51700f8c4573a01c4e55c696db7fe2fea81c4253..1d47c86b5a2724a600db27b86dbde85bc8de9f97 100644 (file)
@@ -1,3 +1,40 @@
+Wed Mar 28 19:20:43 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/testtext.c (create_buffer): Add missing NULL on
+       valist.
+
+       * gtk/gtkcheckmenuitem.c (gtk_check_menu_item_class_init): Fix
+       c-n-p problem with INCONSISTENT property.
+
+        [ Patch from Havoc Pennington  <hp@redhat.com> ]
+
+       * gtk/gtkentry.h (struct _GtkEntryClass): add same populate_popup
+       hook.
+
+       * gtk/gtktextview.h (struct _GtkTextViewClass): add populate_popup
+       signal as a hook for extending the default popup menu
+
+       * gtk/gtkimmulticontext.c (gtk_im_multicontext_append_menuitems):
+       use radio menu items for the input method menuitems
+
+       * gtk/gtkimcontextsimple.c (check_hex): do better validation of 
+       inserted unicode from Ctrl-Shift-hex input method
+
+       * gtk/gtktextbtree.c (_gtk_text_btree_insert): remove utf8
+       validatation here, already done at GtkTextBuffer level.
+
+       * gtk/gtkwidget.c (gtk_widget_class_init): add binding set, add
+       popup_menu run action signal and Shift+F10 and Menu keybindings.
+
+       * gtk/gtkentry.c: implement a default handler for popup_menu
+
+       * gtk/gtktextview.c: implement a default handler for popup_menu
+
+       * gtk/gtkmenu.c (gtk_menu_popup): select first item if popup is
+       from a key event
+       
+       * gtk/gtklabel.c: remove "trailer" cruft
+
 Wed Mar 28 17:27:12 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtkrbtree.c (_gtk_rbtree_reorder): new function to
index 51700f8c4573a01c4e55c696db7fe2fea81c4253..1d47c86b5a2724a600db27b86dbde85bc8de9f97 100644 (file)
@@ -1,3 +1,40 @@
+Wed Mar 28 19:20:43 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/testtext.c (create_buffer): Add missing NULL on
+       valist.
+
+       * gtk/gtkcheckmenuitem.c (gtk_check_menu_item_class_init): Fix
+       c-n-p problem with INCONSISTENT property.
+
+        [ Patch from Havoc Pennington  <hp@redhat.com> ]
+
+       * gtk/gtkentry.h (struct _GtkEntryClass): add same populate_popup
+       hook.
+
+       * gtk/gtktextview.h (struct _GtkTextViewClass): add populate_popup
+       signal as a hook for extending the default popup menu
+
+       * gtk/gtkimmulticontext.c (gtk_im_multicontext_append_menuitems):
+       use radio menu items for the input method menuitems
+
+       * gtk/gtkimcontextsimple.c (check_hex): do better validation of 
+       inserted unicode from Ctrl-Shift-hex input method
+
+       * gtk/gtktextbtree.c (_gtk_text_btree_insert): remove utf8
+       validatation here, already done at GtkTextBuffer level.
+
+       * gtk/gtkwidget.c (gtk_widget_class_init): add binding set, add
+       popup_menu run action signal and Shift+F10 and Menu keybindings.
+
+       * gtk/gtkentry.c: implement a default handler for popup_menu
+
+       * gtk/gtktextview.c: implement a default handler for popup_menu
+
+       * gtk/gtkmenu.c (gtk_menu_popup): select first item if popup is
+       from a key event
+       
+       * gtk/gtklabel.c: remove "trailer" cruft
+
 Wed Mar 28 17:27:12 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtkrbtree.c (_gtk_rbtree_reorder): new function to
index 51700f8c4573a01c4e55c696db7fe2fea81c4253..1d47c86b5a2724a600db27b86dbde85bc8de9f97 100644 (file)
@@ -1,3 +1,40 @@
+Wed Mar 28 19:20:43 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/testtext.c (create_buffer): Add missing NULL on
+       valist.
+
+       * gtk/gtkcheckmenuitem.c (gtk_check_menu_item_class_init): Fix
+       c-n-p problem with INCONSISTENT property.
+
+        [ Patch from Havoc Pennington  <hp@redhat.com> ]
+
+       * gtk/gtkentry.h (struct _GtkEntryClass): add same populate_popup
+       hook.
+
+       * gtk/gtktextview.h (struct _GtkTextViewClass): add populate_popup
+       signal as a hook for extending the default popup menu
+
+       * gtk/gtkimmulticontext.c (gtk_im_multicontext_append_menuitems):
+       use radio menu items for the input method menuitems
+
+       * gtk/gtkimcontextsimple.c (check_hex): do better validation of 
+       inserted unicode from Ctrl-Shift-hex input method
+
+       * gtk/gtktextbtree.c (_gtk_text_btree_insert): remove utf8
+       validatation here, already done at GtkTextBuffer level.
+
+       * gtk/gtkwidget.c (gtk_widget_class_init): add binding set, add
+       popup_menu run action signal and Shift+F10 and Menu keybindings.
+
+       * gtk/gtkentry.c: implement a default handler for popup_menu
+
+       * gtk/gtktextview.c: implement a default handler for popup_menu
+
+       * gtk/gtkmenu.c (gtk_menu_popup): select first item if popup is
+       from a key event
+       
+       * gtk/gtklabel.c: remove "trailer" cruft
+
 Wed Mar 28 17:27:12 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtkrbtree.c (_gtk_rbtree_reorder): new function to
index 51700f8c4573a01c4e55c696db7fe2fea81c4253..1d47c86b5a2724a600db27b86dbde85bc8de9f97 100644 (file)
@@ -1,3 +1,40 @@
+Wed Mar 28 19:20:43 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/testtext.c (create_buffer): Add missing NULL on
+       valist.
+
+       * gtk/gtkcheckmenuitem.c (gtk_check_menu_item_class_init): Fix
+       c-n-p problem with INCONSISTENT property.
+
+        [ Patch from Havoc Pennington  <hp@redhat.com> ]
+
+       * gtk/gtkentry.h (struct _GtkEntryClass): add same populate_popup
+       hook.
+
+       * gtk/gtktextview.h (struct _GtkTextViewClass): add populate_popup
+       signal as a hook for extending the default popup menu
+
+       * gtk/gtkimmulticontext.c (gtk_im_multicontext_append_menuitems):
+       use radio menu items for the input method menuitems
+
+       * gtk/gtkimcontextsimple.c (check_hex): do better validation of 
+       inserted unicode from Ctrl-Shift-hex input method
+
+       * gtk/gtktextbtree.c (_gtk_text_btree_insert): remove utf8
+       validatation here, already done at GtkTextBuffer level.
+
+       * gtk/gtkwidget.c (gtk_widget_class_init): add binding set, add
+       popup_menu run action signal and Shift+F10 and Menu keybindings.
+
+       * gtk/gtkentry.c: implement a default handler for popup_menu
+
+       * gtk/gtktextview.c: implement a default handler for popup_menu
+
+       * gtk/gtkmenu.c (gtk_menu_popup): select first item if popup is
+       from a key event
+       
+       * gtk/gtklabel.c: remove "trailer" cruft
+
 Wed Mar 28 17:27:12 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtkrbtree.c (_gtk_rbtree_reorder): new function to
index 51700f8c4573a01c4e55c696db7fe2fea81c4253..1d47c86b5a2724a600db27b86dbde85bc8de9f97 100644 (file)
@@ -1,3 +1,40 @@
+Wed Mar 28 19:20:43 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/testtext.c (create_buffer): Add missing NULL on
+       valist.
+
+       * gtk/gtkcheckmenuitem.c (gtk_check_menu_item_class_init): Fix
+       c-n-p problem with INCONSISTENT property.
+
+        [ Patch from Havoc Pennington  <hp@redhat.com> ]
+
+       * gtk/gtkentry.h (struct _GtkEntryClass): add same populate_popup
+       hook.
+
+       * gtk/gtktextview.h (struct _GtkTextViewClass): add populate_popup
+       signal as a hook for extending the default popup menu
+
+       * gtk/gtkimmulticontext.c (gtk_im_multicontext_append_menuitems):
+       use radio menu items for the input method menuitems
+
+       * gtk/gtkimcontextsimple.c (check_hex): do better validation of 
+       inserted unicode from Ctrl-Shift-hex input method
+
+       * gtk/gtktextbtree.c (_gtk_text_btree_insert): remove utf8
+       validatation here, already done at GtkTextBuffer level.
+
+       * gtk/gtkwidget.c (gtk_widget_class_init): add binding set, add
+       popup_menu run action signal and Shift+F10 and Menu keybindings.
+
+       * gtk/gtkentry.c: implement a default handler for popup_menu
+
+       * gtk/gtktextview.c: implement a default handler for popup_menu
+
+       * gtk/gtkmenu.c (gtk_menu_popup): select first item if popup is
+       from a key event
+       
+       * gtk/gtklabel.c: remove "trailer" cruft
+
 Wed Mar 28 17:27:12 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtkrbtree.c (_gtk_rbtree_reorder): new function to
index 51700f8c4573a01c4e55c696db7fe2fea81c4253..1d47c86b5a2724a600db27b86dbde85bc8de9f97 100644 (file)
@@ -1,3 +1,40 @@
+Wed Mar 28 19:20:43 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/testtext.c (create_buffer): Add missing NULL on
+       valist.
+
+       * gtk/gtkcheckmenuitem.c (gtk_check_menu_item_class_init): Fix
+       c-n-p problem with INCONSISTENT property.
+
+        [ Patch from Havoc Pennington  <hp@redhat.com> ]
+
+       * gtk/gtkentry.h (struct _GtkEntryClass): add same populate_popup
+       hook.
+
+       * gtk/gtktextview.h (struct _GtkTextViewClass): add populate_popup
+       signal as a hook for extending the default popup menu
+
+       * gtk/gtkimmulticontext.c (gtk_im_multicontext_append_menuitems):
+       use radio menu items for the input method menuitems
+
+       * gtk/gtkimcontextsimple.c (check_hex): do better validation of 
+       inserted unicode from Ctrl-Shift-hex input method
+
+       * gtk/gtktextbtree.c (_gtk_text_btree_insert): remove utf8
+       validatation here, already done at GtkTextBuffer level.
+
+       * gtk/gtkwidget.c (gtk_widget_class_init): add binding set, add
+       popup_menu run action signal and Shift+F10 and Menu keybindings.
+
+       * gtk/gtkentry.c: implement a default handler for popup_menu
+
+       * gtk/gtktextview.c: implement a default handler for popup_menu
+
+       * gtk/gtkmenu.c (gtk_menu_popup): select first item if popup is
+       from a key event
+       
+       * gtk/gtklabel.c: remove "trailer" cruft
+
 Wed Mar 28 17:27:12 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtkrbtree.c (_gtk_rbtree_reorder): new function to
index d76bbe256ff2652b5add1d18537b59bb9698d9e4..efeb6fcf07e464c1fa478cd61dc0adf4688bddf1 100644 (file)
@@ -117,7 +117,7 @@ gtk_check_menu_item_class_init (GtkCheckMenuItemClass *klass)
                                                          G_PARAM_READABLE | G_PARAM_WRITABLE));
   
   g_object_class_install_property (G_OBJECT_CLASS (object_class),
-                                   PROP_ACTIVE,
+                                   PROP_INCONSISTENT,
                                    g_param_spec_boolean ("inconsistent",
                                                          _("Inconsistent"),
                                                          _("Whether to display an \"inconsistent\" state."),
index 046980492aaada9966cbd474805143466bb560d4..9597e85255554552a1fa122ef8ce045cb9148b01 100644 (file)
@@ -58,6 +58,7 @@ enum {
   DELETE_TEXT,
   CHANGED,
   ACTIVATE,
+  POPULATE_POPUP,
   MOVE_CURSOR,
   INSERT_AT_CURSOR,
   DELETE_FROM_CURSOR,
@@ -207,6 +208,7 @@ static void gtk_entry_copy_clipboard     (GtkEntry        *entry);
 static void gtk_entry_paste_clipboard    (GtkEntry        *entry);
 static void gtk_entry_toggle_overwrite   (GtkEntry        *entry);
 static void gtk_entry_real_activate      (GtkEntry        *entry);
+static void gtk_entry_popup_menu         (GtkWidget      *widget);
 
 /* IM Context Callbacks
  */
@@ -248,7 +250,7 @@ static char *       gtk_entry_get_public_chars         (GtkEntry       *entry,
 static void         gtk_entry_paste                    (GtkEntry       *entry,
                                                        GdkAtom         selection);
 static void         gtk_entry_update_primary_selection (GtkEntry       *entry);
-static void         gtk_entry_popup_menu               (GtkEntry       *entry,
+static void         gtk_entry_do_popup                 (GtkEntry       *entry,
                                                        GdkEventButton *event);
 static gboolean     gtk_entry_activate_mnemonic        (GtkWidget     *widget,
                                                        gboolean       group_cycling);
@@ -351,6 +353,8 @@ gtk_entry_class_init (GtkEntryClass *class)
   widget_class->drag_data_get = gtk_entry_drag_data_get;
   widget_class->drag_data_delete = gtk_entry_drag_data_delete;
 
+  widget_class->popup_menu = gtk_entry_popup_menu;
+  
   class->insert_text = gtk_entry_real_insert_text;
   class->delete_text = gtk_entry_real_delete_text;
   class->move_cursor = gtk_entry_move_cursor;
@@ -456,6 +460,14 @@ gtk_entry_class_init (GtkEntryClass *class)
                    gtk_marshal_VOID__VOID,
                    GTK_TYPE_NONE, 0);
 
+  signals[POPULATE_POPUP] =
+    gtk_signal_new ("populate_popup",
+                   GTK_RUN_LAST,
+                   GTK_CLASS_TYPE (object_class),
+                   GTK_SIGNAL_OFFSET (GtkEntryClass, populate_popup),
+                   gtk_marshal_VOID__OBJECT,
+                   GTK_TYPE_NONE, 1, GTK_TYPE_MENU);
+  
  /* Action signals */
   
   signals[ACTIVATE] =
@@ -1312,7 +1324,7 @@ gtk_entry_button_press (GtkWidget      *widget,
     }
   else if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
     {
-      gtk_entry_popup_menu (entry, event);
+      gtk_entry_do_popup (entry, event);
       entry->button = 0;       /* Don't wait for release, since the menu will gtk_grab_add */
 
       return TRUE;
@@ -3149,7 +3161,8 @@ static void
 append_action_signal (GtkEntry     *entry,
                      GtkWidget    *menu,
                      const gchar  *label,
-                     const gchar  *signal)
+                     const gchar  *signal,
+                      gboolean      sensitive)
 {
   GtkWidget *menuitem = gtk_menu_item_new_with_label (label);
 
@@ -3157,6 +3170,8 @@ append_action_signal (GtkEntry     *entry,
   gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
                      GTK_SIGNAL_FUNC (activate_cb), entry);
 
+  gtk_widget_set_sensitive (menuitem, sensitive);
+  
   gtk_widget_show (menuitem);
   gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
 }
@@ -3169,34 +3184,91 @@ popup_menu_detach (GtkWidget *attach_widget,
 }
 
 static void
-gtk_entry_popup_menu (GtkEntry       *entry,
-                     GdkEventButton *event)
+popup_position_func (GtkMenu   *menu,
+                     gint      *x,
+                     gint      *y,
+                     gboolean  *push_in,
+                     gpointer  user_data)
 {
-  if (!entry->popup_menu)
-    {
-      GtkWidget *menuitem;
-      
-      entry->popup_menu = gtk_menu_new ();
+  GtkEntry *entry;
+  GtkWidget *widget;
+  GtkRequisition req;
+  
+  entry = GTK_ENTRY (user_data);  
+  widget = GTK_WIDGET (entry);
+  
+  g_return_if_fail (GTK_WIDGET_REALIZED (entry));
 
-      gtk_menu_attach_to_widget (GTK_MENU (entry->popup_menu),
-                                GTK_WIDGET (entry),
-                                popup_menu_detach);
+  gdk_window_get_origin (widget->window, x, y);      
 
-      append_action_signal (entry, entry->popup_menu, _("Cut"), "cut_clipboard");
-      append_action_signal (entry, entry->popup_menu, _("Copy"), "copy_clipboard");
-      append_action_signal (entry, entry->popup_menu, _("Paste"), "paste_clipboard");
+  gtk_widget_size_request (entry->popup_menu, &req);
+  
+  *x += widget->allocation.width / 2;
+  *y += widget->allocation.height;
 
-      menuitem = gtk_separator_menu_item_new ();
-      gtk_widget_show (menuitem);
-      gtk_menu_shell_append (GTK_MENU_SHELL (entry->popup_menu), menuitem);
+  *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width));
+  *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height));
+}
 
-      gtk_im_multicontext_append_menuitems (GTK_IM_MULTICONTEXT (entry->im_context),
-                                           GTK_MENU_SHELL (entry->popup_menu));
-    }
+static void
+gtk_entry_do_popup (GtkEntry       *entry,
+                    GdkEventButton *event)
+{
 
-  gtk_menu_popup (GTK_MENU (entry->popup_menu), NULL, NULL,
-                 NULL, NULL,
-                 event->button, event->time);
+  GtkWidget *menuitem;
+  GtkWidget *submenu;
+  gboolean have_selection;
+
+  if (entry->popup_menu)
+    gtk_widget_destroy (entry->popup_menu);
+  
+  entry->popup_menu = gtk_menu_new ();
+
+  gtk_menu_attach_to_widget (GTK_MENU (entry->popup_menu),
+                             GTK_WIDGET (entry),
+                             popup_menu_detach);
+
+  have_selection = entry->current_pos != entry->selection_bound;
+  
+  append_action_signal (entry, entry->popup_menu, _("Cut"), "cut_clipboard",
+                        have_selection);
+  append_action_signal (entry, entry->popup_menu, _("Copy"), "copy_clipboard",
+                        have_selection);
+  append_action_signal (entry, entry->popup_menu, _("Paste"), "paste_clipboard",
+                        TRUE);
+
+  menuitem = gtk_separator_menu_item_new ();
+  gtk_widget_show (menuitem);
+  gtk_menu_shell_append (GTK_MENU_SHELL (entry->popup_menu), menuitem);
+      
+  menuitem = gtk_menu_item_new_with_label (_("Input Methods"));
+  gtk_widget_show (menuitem);
+  submenu = gtk_menu_new ();
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
+
+  gtk_menu_shell_append (GTK_MENU_SHELL (entry->popup_menu), menuitem);
+      
+  gtk_im_multicontext_append_menuitems (GTK_IM_MULTICONTEXT (entry->im_context),
+                                        GTK_MENU_SHELL (submenu));
+
+  gtk_signal_emit (GTK_OBJECT (entry),
+                   signals[POPULATE_POPUP],
+                   entry->popup_menu);
+  
+  if (event)
+    gtk_menu_popup (GTK_MENU (entry->popup_menu), NULL, NULL,
+                    NULL, NULL,
+                    event->button, event->time);
+  else
+    gtk_menu_popup (GTK_MENU (entry->popup_menu), NULL, NULL,
+                    popup_position_func, entry,
+                    0, gtk_get_current_event_time ());
+}
+
+static void
+gtk_entry_popup_menu (GtkWidget *widget)
+{
+  gtk_entry_do_popup (GTK_ENTRY (widget), NULL);
 }
 
 static void
index 5ba3df752ffac3bd7af0cd9cdbc1fd1c81795368..f94072b98e0977fa8d987d91a6682f163da2dc44 100644 (file)
@@ -31,6 +31,7 @@
 #include <gdk/gdk.h>
 #include <gtk/gtkeditable.h>
 #include <gtk/gtkimcontext.h>
+#include <gtk/gtkmenu.h>
 #include <pango/pango.h>
 
 #ifdef __cplusplus
@@ -118,6 +119,10 @@ struct _GtkEntryClass
                             gint            start_pos,
                             gint            end_pos);
 
+  /* Hook to customize right-click popup */
+  void (* populate_popup)   (GtkEntry       *entry,
+                             GtkMenu        *menu);
+  
   /* Action signals
    */
   void (* activate)           (GtkEntry       *entry);
index 36da2c96a934a4a6e6f48c61ec7f576dc96c917c..d1c5f543d0baf8a748c08787d5137a623d07ef58 100644 (file)
@@ -827,7 +827,9 @@ gtk_im_context_simple_commit_char (GtkIMContext *context,
   gint len;
 
   GtkIMContextSimple *context_simple = GTK_IM_CONTEXT_SIMPLE (context);
-      
+
+  g_return_if_fail (g_unichar_validate (ch));
+  
   len = g_unichar_to_utf8 (ch, buf);
   buf[len] = '\0';
 
@@ -981,12 +983,10 @@ check_hex (GtkIMContextSimple *context_simple,
     }
   else
     g_string_free (str, TRUE);
-  
-  if (n > 0xFFFF)
-    return FALSE; /* too many digits */
 
-  if (n == 0)
-    return FALSE; /* don't insert nul bytes */
+  /* don't allow invalid Unicode or nul bytes */
+  if (n == 0 || !g_unichar_validate (n))
+    return FALSE;
   
   context_simple->tentative_match = n;
   context_simple->tentative_match_len = n_compose;
index 80e75f0db5229b5e3ee4480b89091a97895917f3..341b56a02dbb29b948bcfe2f964bb9896d2783e5 100644 (file)
@@ -28,7 +28,7 @@
 #include "gtksignal.h"
 #include "gtkimmulticontext.h"
 #include "gtkimmodule.h"
-#include "gtkmenuitem.h"
+#include "gtkradiomenuitem.h"
 
 static void     gtk_im_multicontext_class_init         (GtkIMMulticontextClass  *class);
 static void     gtk_im_multicontext_init               (GtkIMMulticontext       *im_multicontext);
@@ -341,6 +341,7 @@ gtk_im_multicontext_append_menuitems (GtkIMMulticontext *context,
 {
   const GtkIMContextInfo **contexts;
   gint n_contexts, i;
+  GSList *group = NULL;
   
   _gtk_im_module_list (&contexts, &n_contexts);
 
@@ -348,8 +349,17 @@ gtk_im_multicontext_append_menuitems (GtkIMMulticontext *context,
     {
       GtkWidget *menuitem;
 
-      menuitem = gtk_menu_item_new_with_label (contexts[i]->context_name);
-
+      menuitem = gtk_radio_menu_item_new_with_label (group,
+                                                     contexts[i]->context_name);
+      
+      if ((global_context_id == NULL && group == NULL) ||
+          (global_context_id &&
+           strcmp (contexts[i]->context_id, global_context_id) == 0))
+        gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menuitem),
+                                        TRUE);
+      
+      group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem));
+      
       gtk_object_set_data (GTK_OBJECT (menuitem), "gtk-context-id",
                           (char *)contexts[i]->context_id);
       gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
index 4d26c93c68cb047662b3081533b4c39b01cdd361..3de7d6d7d34be10dc5fc64aacf1d20ba2366873c 100644 (file)
@@ -518,7 +518,6 @@ gtk_menu_popup (GtkMenu                 *menu,
       if ((current_event->type != GDK_BUTTON_PRESS) &&
          (current_event->type != GDK_ENTER_NOTIFY))
        menu_shell->ignore_enter = TRUE;
-      gdk_event_free (current_event);
     }
 
   if (menu->torn_off)
@@ -542,6 +541,24 @@ gtk_menu_popup (GtkMenu                *menu,
   gtk_widget_show (GTK_WIDGET (menu));
   gtk_widget_show (menu->toplevel);
 
+  if (current_event)
+    {
+      /* Also, if we're popping up from a key event, select the first
+       * item in the menu. Bad hack, but no better way to do it
+       * in current menu framework.
+       */
+      if (current_event->type == GDK_KEY_PRESS &&
+          GTK_MENU_SHELL (menu)->children)
+        {
+          gtk_menu_shell_select_item (GTK_MENU_SHELL (menu),
+                                      GTK_MENU_SHELL (menu)->children->data);
+        }
+      
+      gdk_event_free (current_event);
+    }
+  
+  gtk_menu_scroll_to (menu, menu->scroll_offset);
+
   /* Find the last viewable ancestor, and make an X grab on it
    */
   parent = GTK_WIDGET (menu);
@@ -576,15 +593,13 @@ gtk_menu_popup (GtkMenu               *menu,
                             NULL, NULL, activate_time) == 0))
        {
          if (gdk_keyboard_grab (xgrab_shell->window, TRUE,
-                             activate_time) == 0)
+                                 activate_time) == 0)
            GTK_MENU_SHELL (xgrab_shell)->have_xgrab = TRUE;
          else
            gdk_pointer_ungrab (activate_time);
        }
     }
 
-  gtk_menu_scroll_to (menu, menu->scroll_offset);
-
   gtk_grab_add (GTK_WIDGET (menu));
 }
 
index 601ab8a942bb50176a97ccd75daa1be3d5b7d678..58e0d0c79e635297d1c3597809dfa5037a1fdcb8 100644 (file)
@@ -959,8 +959,6 @@ _gtk_text_btree_insert (GtkTextIter *iter,
   /* Invalidate all iterators */
   chars_changed (tree);
   segments_changed (tree);
-
-  g_assert (g_utf8_validate (text, len, NULL));
   
   /*
    * Chop the text up into lines and create a new segment for
index 292e63ddc9b1ce162554f69889ad514d13f768e4..1074ca0f9a0cf7db8e97dcd1adb33ee8d5c82569 100644 (file)
@@ -477,7 +477,7 @@ gtk_text_buffer_emit_insert (GtkTextBuffer *buffer,
   if (len < 0)
     len = strlen (text);
 
-  g_assert (g_utf8_validate (text, len, NULL));
+  g_return_if_fail (g_utf8_validate (text, len, NULL));
   
   if (len > 0)
     {
index 3ee94dd8d7315309c7b569a28bde44c49d58595d..b60250b739e8aad97191c992e71d6d8f68be0651 100644 (file)
@@ -99,6 +99,8 @@ struct _GtkTextPendingScroll
   
 enum
 {
+  SET_SCROLL_ADJUSTMENTS,
+  POPULATE_POPUP,
   MOVE_CURSOR,
   SET_ANCHOR,
   INSERT_AT_CURSOR,
@@ -107,7 +109,6 @@ enum
   COPY_CLIPBOARD,
   PASTE_CLIPBOARD,
   TOGGLE_OVERWRITE,
-  SET_SCROLL_ADJUSTMENTS,
   LAST_SIGNAL
 };
 
@@ -207,6 +208,7 @@ static void     gtk_text_view_drag_data_received (GtkWidget        *widget,
 static void gtk_text_view_set_scroll_adjustments (GtkTextView   *text_view,
                                                   GtkAdjustment *hadj,
                                                   GtkAdjustment *vadj);
+static void gtk_text_view_popup_menu             (GtkWidget     *widget);
 
 static void gtk_text_view_move_cursor      (GtkTextView           *text_view,
                                             GtkMovementStep        step,
@@ -270,7 +272,7 @@ static void gtk_text_view_set_virtual_cursor_pos (GtkTextView       *text_view,
 static GtkAdjustment* get_hadjustment            (GtkTextView       *text_view);
 static GtkAdjustment* get_vadjustment            (GtkTextView       *text_view);
 
-static void gtk_text_view_popup_menu             (GtkTextView       *text_view,
+static void gtk_text_view_do_popup               (GtkTextView       *text_view,
                                                  GdkEventButton    *event);
 
 static void gtk_text_view_queue_scroll           (GtkTextView   *text_view,
@@ -473,6 +475,8 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
   widget_class->drag_drop = gtk_text_view_drag_drop;
   widget_class->drag_data_received = gtk_text_view_drag_data_received;
 
+  widget_class->popup_menu = gtk_text_view_popup_menu;
+  
   container_class->add = gtk_text_view_add;
   container_class->remove = gtk_text_view_remove;
   container_class->forall = gtk_text_view_forall;
@@ -592,6 +596,14 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
                     GTK_TYPE_NONE, 2, GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
   widget_class->set_scroll_adjustments_signal = signals[SET_SCROLL_ADJUSTMENTS];
 
+  signals[POPULATE_POPUP] =
+    gtk_signal_new ("populate_popup",
+                    GTK_RUN_LAST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GtkTextViewClass, populate_popup),
+                    gtk_marshal_VOID__OBJECT,
+                    GTK_TYPE_NONE, 1, GTK_TYPE_MENU);
+  
   /*
    * Key bindings
    */
@@ -3044,7 +3056,7 @@ gtk_text_view_button_press_event (GtkWidget *widget, GdkEventButton *event)
         }
       else if (event->button == 3)
         {
-         gtk_text_view_popup_menu (text_view, event);
+         gtk_text_view_do_popup (text_view, event);
         }
     }
   else if ((event->type == GDK_2BUTTON_PRESS ||
@@ -4866,7 +4878,8 @@ static void
 append_action_signal (GtkTextView  *text_view,
                      GtkWidget    *menu,
                      const gchar  *label,
-                     const gchar  *signal)
+                     const gchar  *signal,
+                      gboolean      sensitive)
 {
   GtkWidget *menuitem = gtk_menu_item_new_with_label (label);
 
@@ -4874,6 +4887,8 @@ append_action_signal (GtkTextView  *text_view,
   gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
                      GTK_SIGNAL_FUNC (activate_cb), text_view);
 
+  gtk_widget_set_sensitive (menuitem, sensitive);
+  
   gtk_widget_show (menuitem);
   gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
 }
@@ -4886,37 +4901,127 @@ popup_menu_detach (GtkWidget *attach_widget,
 }
 
 static void
-gtk_text_view_popup_menu (GtkTextView    *text_view,
-                         GdkEventButton *event)
+popup_position_func (GtkMenu   *menu,
+                     gint      *x,
+                     gint      *y,
+                     gboolean  *push_in,
+                     gpointer  user_data)
 {
-  if (!text_view->popup_menu)
-    {
-      GtkWidget *menuitem;
-
-      text_view->popup_menu = gtk_menu_new ();
+  GtkTextView *text_view;
+  GtkWidget *widget;
+  GdkRectangle cursor_rect;
+  GdkRectangle onscreen_rect;
+  gint root_x, root_y;
+  GtkTextIter iter;
+  GtkRequisition req;      
+  
+  text_view = GTK_TEXT_VIEW (user_data);
+  widget = GTK_WIDGET (text_view);
+  
+  g_return_if_fail (GTK_WIDGET_REALIZED (text_view));
 
-      gtk_menu_attach_to_widget (GTK_MENU (text_view->popup_menu),
-                                GTK_WIDGET (text_view),
-                                popup_menu_detach);
+  gdk_window_get_origin (widget->window, &root_x, &root_y);
 
-      append_action_signal (text_view, text_view->popup_menu, _("Cut"), "cut_clipboard");
-      append_action_signal (text_view, text_view->popup_menu, _("Copy"), "copy_clipboard");
-      append_action_signal (text_view, text_view->popup_menu, _("Paste"), "paste_clipboard");
+  gtk_text_buffer_get_iter_at_mark (get_buffer (text_view),
+                                    &iter,
+                                    gtk_text_buffer_get_insert (get_buffer (text_view)));
 
-      menuitem = gtk_separator_menu_item_new ();
-      gtk_widget_show (menuitem);
-      gtk_menu_shell_append (GTK_MENU_SHELL (text_view->popup_menu), menuitem);
+  gtk_text_view_get_iter_location (text_view,
+                                   &iter,
+                                   &cursor_rect);
 
-      gtk_im_multicontext_append_menuitems (GTK_IM_MULTICONTEXT (text_view->im_context),
-                                           GTK_MENU_SHELL (text_view->popup_menu));
+  gtk_text_view_get_visible_rect (text_view, &onscreen_rect);
+  
+  gtk_widget_size_request (text_view->popup_menu, &req);
+
+  /* can't use rectangle_intersect since cursor rect can have 0 width */
+  if (cursor_rect.x >= onscreen_rect.x &&
+      cursor_rect.x < onscreen_rect.x + onscreen_rect.width &&
+      cursor_rect.y >= onscreen_rect.y &&
+      cursor_rect.y < onscreen_rect.y + onscreen_rect.height)
+    {    
+      gtk_text_view_buffer_to_window_coords (text_view,
+                                             GTK_TEXT_WINDOW_WIDGET,
+                                             cursor_rect.x, cursor_rect.y,
+                                             &cursor_rect.x, &cursor_rect.y);
+
+      *x = root_x + cursor_rect.x + cursor_rect.width;
+      *y = root_y + cursor_rect.y + cursor_rect.height;
     }
+  else
+    {
+      /* Just center the menu, since cursor is offscreen. */      
+      *x = root_x + (widget->allocation.width / 2 - req.width / 2);
+      *y = root_y + (widget->allocation.height / 2 - req.height / 2);      
+    }
+
+  /* Ensure sanity */
+  *x = CLAMP (*x, root_x, (root_x + widget->allocation.width));
+  *y = CLAMP (*y, root_y, (root_y + widget->allocation.height));
 
-  gtk_menu_popup (GTK_MENU (text_view->popup_menu), NULL, NULL,
-                 NULL, NULL,
-                 event->button, event->time);
+  *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width));
+  *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height));
 }
 
+static void
+gtk_text_view_do_popup (GtkTextView    *text_view,
+                        GdkEventButton *event)
+{
+  GtkWidget *menuitem;
+  GtkWidget *submenu;
+  gboolean have_selection;
+  
+  if (text_view->popup_menu)
+    gtk_widget_destroy (text_view->popup_menu);
+  
+  text_view->popup_menu = gtk_menu_new ();
+
+  gtk_menu_attach_to_widget (GTK_MENU (text_view->popup_menu),
+                             GTK_WIDGET (text_view),
+                             popup_menu_detach);
+
+  have_selection = gtk_text_buffer_get_selection_bounds (get_buffer (text_view),
+                                                         NULL, NULL);
+  
+  append_action_signal (text_view, text_view->popup_menu, _("Cut"), "cut_clipboard",
+                        have_selection);
+  append_action_signal (text_view, text_view->popup_menu, _("Copy"), "copy_clipboard",
+                        have_selection);
+  append_action_signal (text_view, text_view->popup_menu, _("Paste"), "paste_clipboard",
+                        TRUE);
+
+  menuitem = gtk_separator_menu_item_new ();
+  gtk_widget_show (menuitem);
+  gtk_menu_shell_append (GTK_MENU_SHELL (text_view->popup_menu), menuitem);
+      
+  menuitem = gtk_menu_item_new_with_label (_("Input Methods"));
+  gtk_widget_show (menuitem);
+  submenu = gtk_menu_new ();
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
+  gtk_menu_shell_append (GTK_MENU_SHELL (text_view->popup_menu), menuitem);
+
+  gtk_im_multicontext_append_menuitems (GTK_IM_MULTICONTEXT (text_view->im_context),
+                                        GTK_MENU_SHELL (submenu));
+
+  gtk_signal_emit (GTK_OBJECT (text_view),
+                   signals[POPULATE_POPUP],
+                   text_view->popup_menu);
+  
+  if (event)
+    gtk_menu_popup (GTK_MENU (text_view->popup_menu), NULL, NULL,
+                    NULL, NULL,
+                    event->button, event->time);
+  else
+    gtk_menu_popup (GTK_MENU (text_view->popup_menu), NULL, NULL,
+                    popup_position_func, text_view,
+                    0, gtk_get_current_event_time ());
+}
 
+static void
+gtk_text_view_popup_menu (GtkWidget *widget)
+{
+  gtk_text_view_do_popup (GTK_TEXT_VIEW (widget), NULL);  
+}
 
 /* Child GdkWindows */
 
index b60ccd971910df7bd9330d1bfce5c97704726e62..9224657ca3cbcd88ad5a4ff48e51c4c37f1dc54a 100644 (file)
@@ -30,6 +30,7 @@
 #include <gtk/gtkcontainer.h>
 #include <gtk/gtkimcontext.h>
 #include <gtk/gtktextbuffer.h>
+#include <gtk/gtkmenu.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -148,6 +149,13 @@ struct _GtkTextViewClass
 {
   GtkContainerClass parent_class;
 
+  void (* set_scroll_adjustments)   (GtkTextView    *text_view,
+                                     GtkAdjustment  *hadjustment,
+                                     GtkAdjustment  *vadjustment);
+
+  void (* populate_popup)           (GtkTextView    *text_view,
+                                     GtkMenu        *menu);
+  
   /* These are all RUN_ACTION signals for keybindings */
 
   /* move insertion point */
@@ -171,9 +179,6 @@ struct _GtkTextViewClass
   void (* paste_clipboard) (GtkTextView *text_view);
   /* overwrite */
   void (* toggle_overwrite) (GtkTextView *text_view);
-  void (* set_scroll_adjustments)   (GtkTextView    *text_view,
-                                     GtkAdjustment  *hadjustment,
-                                     GtkAdjustment  *vadjustment);
 };
 
 GtkType        gtk_text_view_get_type              (void) G_GNUC_CONST;
index 831e089dc2b282ecfd8efbe0fea92e7cb0c70f3a..7274923db44aae041fbf6bc9d5f7ff6d18f4d757 100644 (file)
@@ -40,6 +40,7 @@
 #include "gdk/gdk.h"
 #include "gdk/gdkprivate.h" /* Used in gtk_reset_shapes_recurse to avoid copy */
 #include "gobject/gvaluecollector.h"
+#include "gdk/gdkkeysyms.h"
 
 
 #define WIDGET_CLASS(w)         GTK_WIDGET_GET_CLASS (w)
@@ -101,6 +102,7 @@ enum {
   NO_EXPOSE_EVENT,
   VISIBILITY_NOTIFY_EVENT,
   WINDOW_STATE_EVENT,
+  POPUP_MENU,
   LAST_SIGNAL
 };
 
@@ -281,6 +283,7 @@ gtk_widget_class_init (GtkWidgetClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
+  GtkBindingSet *binding_set;
   
   parent_class = gtk_type_class (GTK_TYPE_OBJECT);
 
@@ -811,6 +814,21 @@ gtk_widget_class_init (GtkWidgetClass *klass)
                     gtk_marshal_BOOLEAN__BOXED,
                    GTK_TYPE_BOOL, 1,
                    GTK_TYPE_GDK_EVENT);
+  widget_signals[POPUP_MENU] =
+    gtk_signal_new ("popup_menu",
+                   GTK_RUN_LAST | GTK_RUN_ACTION,
+                   GTK_CLASS_TYPE (object_class),
+                   GTK_SIGNAL_OFFSET (GtkWidgetClass, popup_menu),
+                    gtk_marshal_NONE__NONE,
+                   GTK_TYPE_NONE, 0);
+  
+  binding_set = gtk_binding_set_by_class (klass);
+
+  gtk_binding_entry_add_signal (binding_set, GDK_F10, GDK_SHIFT_MASK,
+                                "popup_menu", 0);
+
+  gtk_binding_entry_add_signal (binding_set, GDK_Menu, 0,
+                                "popup_menu", 0);  
 }
 
 static void
index 3343045d24ba2d6ac19f7500c2df2f5b5799bcaa..9e37df24f96f86e41ba2ee2685de881891f9f778 100644 (file)
@@ -377,8 +377,11 @@ struct _GtkWidgetClass
                                    GtkSelectionData   *selection_data,
                                    guint               info,
                                    guint               time);
+
+  /* Signals used only for keybindings */
+  void (* popup_menu)              (GtkWidget          *widget);
   
-  /* Padding for future expandsion */
+  /* Padding for future expansion */
   GtkFunction pad1;
   GtkFunction pad2;
   GtkFunction pad3;
index ee732ff90252dc1174e4a529c1802de544c44d82..fe1a009fdbe3a61cf757b079ea5126ed4d8e9a87 100644 (file)
@@ -390,7 +390,7 @@ setup_tag (GtkTextTag *tag)
 {
   g_signal_connect_data (G_OBJECT (tag),
                          "event",
-                         tag_event_handler,
+                         G_CALLBACK (tag_event_handler),
                          NULL, NULL, FALSE, FALSE);
 }
 
@@ -1419,7 +1419,7 @@ create_buffer (void)
     }
   
   buffer->invisible_tag = gtk_text_buffer_create_tag (buffer->buffer, NULL,
-                                                      "invisible", TRUE);
+                                                      "invisible", TRUE, NULL);
   
   buffer->not_editable_tag =
     gtk_text_buffer_create_tag (buffer->buffer, NULL,
index ee732ff90252dc1174e4a529c1802de544c44d82..fe1a009fdbe3a61cf757b079ea5126ed4d8e9a87 100644 (file)
@@ -390,7 +390,7 @@ setup_tag (GtkTextTag *tag)
 {
   g_signal_connect_data (G_OBJECT (tag),
                          "event",
-                         tag_event_handler,
+                         G_CALLBACK (tag_event_handler),
                          NULL, NULL, FALSE, FALSE);
 }
 
@@ -1419,7 +1419,7 @@ create_buffer (void)
     }
   
   buffer->invisible_tag = gtk_text_buffer_create_tag (buffer->buffer, NULL,
-                                                      "invisible", TRUE);
+                                                      "invisible", TRUE, NULL);
   
   buffer->not_editable_tag =
     gtk_text_buffer_create_tag (buffer->buffer, NULL,